package com.example.demo.leetcode.thread;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 *  使用CallerRunsPolicy 策略，
 *  即使主线程执行任务并抛出异常也会被捕获打印，不影响线程执行
 *
 */
public class MyThreadPool {

    private static ThreadPoolExecutor threadPoolExecutor;

    private static final Integer queueSize = 100;

    private static final Integer corePoolSize = 5;

     public static void initOutOrderThreadPoolExecutor() {
        long keepAliveTime = 0;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(queueSize);
        // 任务满之后，任务会被当前调用 executor 线程执行
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
        threadPoolExecutor =
            new ThreadPoolExecutor(corePoolSize, corePoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler);
    }

    public static void main(String[] args) {
        initOutOrderThreadPoolExecutor();
        List<Future> list = new ArrayList<>();
        for(int i = 0; i< 50; i++){
            Future future = threadPoolExecutor.submit(new MyThread());
            list.add(future);
        }

        for(Future future1 : list){
            try {
                future1.get(6 * 1000,TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }
        System.out.println("all thread end=====");
    }

    static class MyThread implements Callable {
        @Override public Object call() throws Exception {

            String name = Thread.currentThread().getName();
            System.out.println(Thread.currentThread().getName() + "start===");
            Thread.sleep(4 * 1000);
            if (true) {
                throw new RuntimeException(name+" exception");
            }
            System.out.println(Thread.currentThread().getName() + "end===");
            return null;
        }
    }


}
